﻿#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine.UI;

public class BuildHelper : MonoBehaviour
{
    public enum ObjectType
    {
        ENone,
        EFBX,
        EPerfab,
        EOther,
    }

    public static string U3dAssetName = "Unity3D";
    public static string OutPath = "Unity3D";

    public static string ABWin = "Assets/StreamingAssets/ABWin";
    public static string ABAndroid = "Assets/StreamingAssets/ABAndroid";
    public static string ABIOS = "Assets/StreamingAssets/ABIOS";

    public static string GetPath(BuildTarget target)
    {
        string str = ABWin;
        switch (target)
        {
            case BuildTarget.StandaloneWindows:
                str = ABWin;
                break;
            case BuildTarget.Android:
                str = ABAndroid;
                break;
            case BuildTarget.iOS:
                str = ABIOS;
                break;
            default:
                break;
        }
        return str;
    }

    public static void SetPath(BuildTarget target, string path)
    {
        switch (target)
        {
            case BuildTarget.StandaloneWindows:
                ABWin = path;
                break;
            case BuildTarget.Android:
                ABAndroid = path;
                break;
            case BuildTarget.iOS:
                ABIOS = path;
                break;
            default:
                break;
        }
    }



    static void PrintABInfo(AssetBundleManifest mainifest)
    {
        if (mainifest == null)
        {
            Debug.LogError("ab error");
        }
        else
        {
            string[] strList = mainifest.GetAllAssetBundles();
            StringBuilder sb = new StringBuilder();
            foreach (var item in strList)
            {
                sb.AppendLine(item);
            }

            Debug.Log("输出AB包\n" + sb.ToString());
        }
    }

    static void BuildAssetBundle(BuildTarget buildTarget)
    {
        string path = GetPath(buildTarget);
        var mainifest = BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.StrictMode,
                buildTarget);

        PrintABInfo(mainifest);
    }

    static void BuildAssetBundleSelected(BuildTarget buildTarget, ObjectType otype, Object[] selection = null)
    {
        selection = selection ?? Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        if (selection.Length > 0)
        {
            AssetBundleBuild[] abAry = new AssetBundleBuild[selection.Length];
            int index = 0;
            foreach (Object obj in selection)
            {
                string fullpath = AssetDatabase.GetAssetPath(obj);
                obj.name = obj.name.ToLower();
                switch (otype)
                {

                    case ObjectType.EPerfab:
                        if (fullpath.EndsWith(".prefab"))
                        {
                            string filename = Path.GetFileNameWithoutExtension(fullpath);
                            string path1 = GetPath(buildTarget);
                            abAry[index] = new AssetBundleBuild()
                            {
                                addressableNames = new string[] { fullpath },
                                assetBundleName = filename,
                                assetBundleVariant = U3dAssetName,
                                assetNames = new string[] { fullpath },
                            };
                            var mainifest = BuildPipeline.BuildAssetBundles(path1, abAry, BuildAssetBundleOptions.StrictMode, buildTarget);
                            PrintABInfo(mainifest);
                        }
                        break;
                }
                index++;
            }
        }
    }

    //全部文件打包成一个AB
    public static void BuildAssetOneAB(BuildTarget buildTarget, ObjectType otype, string abName = null, BuildAssetBundleOptions option = BuildAssetBundleOptions.None, Object[] selection = null)
    {
        selection = selection ?? Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        if (selection.Length > 0)
        {
            if (abName == null)
            {
                abName = Selection.objects[0].name;
            }

            AssetBundleBuild[] abAry = new AssetBundleBuild[1];
            AssetBundleBuild ab = new AssetBundleBuild();

            ab.addressableNames = new string[selection.Length];
            ab.assetNames = new string[selection.Length];
            int index = 0;
            foreach (Object obj in selection)
            {
                string fullpath = AssetDatabase.GetAssetPath(obj);
                switch (otype)
                {
                    case ObjectType.EPerfab:
                        if (fullpath.EndsWith(".prefab"))
                        {
                            string filename = Path.GetFileNameWithoutExtension(fullpath);
                            ab.addressableNames[index] = fullpath;
                            ab.assetBundleName = abName;
                            ab.assetBundleVariant = U3dAssetName;
                            ab.assetNames[index] = fullpath;
                        }
                        break;
                }
                index++;
            }
            abAry[0] = ab;
            string path1 = GetPath(buildTarget);
            var mainifest = BuildPipeline.BuildAssetBundles(path1, abAry, option, buildTarget);
            PrintABInfo(mainifest);
        }
    }


    #region Menu All AB
    [MenuItem("Build/Asset Bundle/Build Single (StandaloneWindows)")]
    static void AssetBundle_BuildStandaloneWindows()
    {
        BuildAssetBundle(BuildTarget.StandaloneWindows);
    }

    [MenuItem("Build/Asset Bundle/Build Single (iPhone)")]
    static void AssetBundle_BuildiPhone()
    {
        BuildAssetBundle(BuildTarget.iOS);
    }

    [MenuItem("Build/Asset Bundle/Build Single (android)")]
    static void AssetBundle_BuildAndroid()
    {
        BuildAssetBundle(BuildTarget.Android);
    }
    #endregion

    #region Menu Select Object AB
    [MenuItem("Build/Asset Bundle/Build Selected (StandaloneWindows)")]
    static void AssetBundle_BuildStandaloneWindowsSelected_FERFAB()
    {
        BuildAssetBundleSelected(BuildTarget.StandaloneWindows, ObjectType.EPerfab);
    }


    [MenuItem("Build/Asset Bundle/Build Selected (iPhone)")]
    static void AssetBundle_BuildiPhoneSelected_FERFAB()
    {
        BuildAssetBundleSelected(BuildTarget.iOS, ObjectType.EPerfab);
    }

    [MenuItem("Build/Asset Bundle/Build Selected (android)")]
    static void AssetBundle_BuildAndroidSelected_FERFAB()
    {
        BuildAssetBundleSelected(BuildTarget.Android, ObjectType.EPerfab);
    }

    #endregion

    #region Select Object One AB
    [MenuItem("Build/Asset Bundle/Build Selected One AB (StandaloneWindows)")]
    static void ABOne_WindowsSelected()
    {
        BuildAssetOneAB(BuildTarget.StandaloneWindows, ObjectType.EPerfab);
    }


    [MenuItem("Build/Asset Bundle/Build Selected One AB (iPhone)")]
    static void ABOne_Iphone()
    {
        BuildAssetOneAB(BuildTarget.iOS, ObjectType.EPerfab);
    }

    [MenuItem("Build/Asset Bundle/Build Selected One AB (android)")]
    static void ABOne_Android()
    {
        BuildAssetOneAB(BuildTarget.Android, ObjectType.EPerfab);
    }
    #endregion

    #region Map
    static void BuildUnity(BuildTarget target, Object[] selection = null)
    {
        string productPath = EditorUtility.SaveFolderPanel("Save Resource", "", "");
        if (productPath.Length != 0)
        {
            selection = selection ?? Selection.GetFiltered(typeof(Object), SelectionMode.TopLevel);
            foreach (Object obj in selection)
            {
                string fullpath = AssetDatabase.GetAssetPath(obj);
                string filename = Path.GetFileNameWithoutExtension(fullpath);
                string targetPath = productPath + "/" + filename + U3dAssetName;
                if (targetPath.Length != 0)
                {
                    if (fullpath.EndsWith(".unity"))
                    {
                        BuildPipeline.BuildPlayer(new string[] { fullpath },
                            targetPath,
                            target, BuildOptions.BuildAdditionalStreamedScenes);
                    }
                }
            }
        }
    }

    [MenuItem("Build/Map/Windows")]
    static void Player_BuildStandaloneWindows()
    {
        BuildUnity(BuildTarget.StandaloneWindows);
    }

    [MenuItem("Build/Map/Android")]
    static void Player_BuildAndroidPlayer()
    {
        BuildUnity(BuildTarget.Android);
    }

    [MenuItem("Build/Map/iPhone")]
    static void Player_BuildiPhone()
    {
        BuildUnity(BuildTarget.iOS);
    }

    #endregion



    private static void GetAllFilePath(string path, ArrayList list, List<string> allows = null)
    {
        if (path != null)
        {
            string[] fileEntries = Directory.GetFiles(path);
            for (int i = 0; i < fileEntries.Length; i++)
            {
                string filePath = fileEntries[i];
                string sf = filePath.ToLower();
                if (allows != null)
                {
                    bool isAllow = false;
                    foreach (string allow in allows)
                    {
                        if (sf.EndsWith(allow))
                            isAllow = true;
                    }
                    if (!isAllow)
                        continue;
                }
                filePath = filePath.Replace("\\", "/");
                list.Add(filePath);
            }
            try
            {
                string[] files = Directory.GetDirectories(path);
                foreach (string file in files)
                {
                    try
                    {
                        GetAllFilePath(file, list, allows);
                    }
                    catch (IOException)
                    {
                    }
                }
            }
            catch (IOException)
            {
            }
        }
    }

    #region bulid all

    private static void DeleteAllByFullPath(string deletePath)
    {
        if (Directory.Exists(deletePath))
        {
            DirectoryInfo direction = new DirectoryInfo(deletePath);
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            if (files == null) return;

            for (int i = files.Length - 1; i >= 0; --i)
            {
                files[i].Delete();
            }
        }
    }

    private static Object[] GetAllObjectByFullPath(string fullPath)
    {
        if (Directory.Exists(fullPath))
        {
            DirectoryInfo direction = new DirectoryInfo(fullPath);
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            if (files == null) return null;

            //Debug.Log( files.Length );

            List<Object> selection = new List<Object>();

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Name.EndsWith(".meta"))
                {
                    continue;
                }
                //Debug.Log( "Name:" + files[i].Name );
                var temp = AssetDatabase.LoadAssetAtPath<Object>(string.Format("{0}{1}", fullPath, files[i].Name));
                if (temp != null)
                    selection.Add(temp);
            }

            return selection.ToArray();
        }
        return null;
    }

    private static void AB_BuildAllModelByBuildTarget(BuildTarget bt)
    {
        string sourcePath = "Assets/RawAssets/ExportModel/";
        string targetPath = "Assets/StreamingAssets/Models/";
        DeleteAllByFullPath(targetPath);
        BuildAssetBundleSelected(bt, ObjectType.EPerfab, GetAllObjectByFullPath(sourcePath));
    }

    private static void AB_BuildAllSceneByBuildTarget(BuildTarget bt)
    {
        string sourcePath = "Assets/RawAssets/Scene/ExportMap/";
        string targetPath = "Assets/StreamingAssets/Scenes/";
        DeleteAllByFullPath(targetPath);
        BuildUnity(bt, GetAllObjectByFullPath(sourcePath));
    }

    [MenuItem("Build/Asset Bundle/Build All/Model/StandaloneWindows")]
    static void AssetBundle_BuildAllModel_StandaloneWindows()
    {
        AB_BuildAllModelByBuildTarget(BuildTarget.StandaloneWindows);
    }

    [MenuItem("Build/Asset Bundle/Build All/Model/iPhone")]
    static void AssetBundle_BuildAllModel_iPhone()
    {
        AB_BuildAllModelByBuildTarget(BuildTarget.iOS);
    }

    [MenuItem("Build/Asset Bundle/Build All/Model/android")]
    static void AssetBundle_BuildAllModel_android()
    {
        AB_BuildAllModelByBuildTarget(BuildTarget.Android);
    }

    [MenuItem("Build/Asset Bundle/Build All/Scene/StandaloneWindows")]
    static void AssetBundle_BuildAllScene_StandaloneWindows()
    {
        AB_BuildAllSceneByBuildTarget(BuildTarget.StandaloneWindows);
    }

    [MenuItem("Build/Asset Bundle/Build All/Scene/iPhone")]
    static void AssetBundle_BuildAllScene_iPhone()
    {
        AB_BuildAllSceneByBuildTarget(BuildTarget.iOS);
    }

    [MenuItem("Build/Asset Bundle/Build All/Scene/android")]
    static void AssetBundle_BuildAllScene_android()
    {
        AB_BuildAllSceneByBuildTarget(BuildTarget.Android);
    }

    #endregion



}

#endif
